﻿#include "ActorManager.h"

ActorManager::ActorManager()
{
    m_volumeActors = vtkSmartPointer<vtkActorCollection>::New();
    m_faceActors = vtkSmartPointer<vtkActorCollection>::New();
    m_edgeActors = vtkSmartPointer<vtkActorCollection>::New();
    m_pointActors = vtkSmartPointer<vtkActorCollection>::New();
}

ActorManager::~ActorManager()
{
}

void ActorManager::AddActor(vtkActor* actor, PickMode mode)
{
    switch(mode)
    {
    case PickMode::VOLUME:
        m_volumeActors->AddItem(actor);
        break;

    case PickMode::FACE:
        m_faceActors->AddItem(actor);
        break;

    case PickMode::EDGE:
        m_edgeActors->AddItem(actor);
        break;

    case PickMode::POINT:
        m_pointActors->AddItem(actor);
        break;
    }

    m_actorInfoMap[actor].mode = mode;
}

void  ActorManager::RemoveActor(vtkActor* actor)
{
    if(m_actorInfoMap.find(actor) != m_actorInfoMap.end())
    {
        ActorInfo info = m_actorInfoMap[actor];
        switch(info.mode)
        {
        case PickMode::VOLUME: m_volumeActors->RemoveItem(actor); break;
        case PickMode::FACE: m_faceActors->RemoveItem(actor); break;
        case PickMode::EDGE: m_edgeActors->RemoveItem(actor); break;
        case PickMode::POINT: m_pointActors->RemoveItem(actor); break;
        }

        m_actorInfoMap.erase(actor);
    }
}

ActorInfo ActorManager::GetActorInfo(vtkActor* actor) const
{
    auto it = m_actorInfoMap.find(actor);
    if(it != m_actorInfoMap.end())
    {
        return it->second;
    }
    return {PickMode::VOLUME, "Unknown", -1};
}

std::vector<vtkActor*> ActorManager::GetAllActors() const
{
    std::vector<vtkActor*> actors;

    // 从所有分类中收集Actor
    auto addActorsFromCollection = [&](vtkActorCollection* collection)
        {
            collection->InitTraversal();
            vtkActor* actor;
            while((actor = collection->GetNextActor()) != nullptr)
            {
                actors.push_back(actor);
            }
        };

    addActorsFromCollection(m_volumeActors);
    addActorsFromCollection(m_faceActors);
    addActorsFromCollection(m_edgeActors);
    addActorsFromCollection(m_pointActors);

    return actors;
}

vtkActor* ActorManager::FindActorByName(const std::string& name) const
{
    for(const auto& pair : m_actorInfoMap)
    {
        if(pair.second.name == name)
        {
            return pair.first;
        }
    }
    return nullptr;
}

vtkActorCollection* ActorManager::GetVolumeActors() const
{
    return m_volumeActors;
}

vtkActorCollection* ActorManager::GetFaceActors() const
{
    return m_faceActors;
}

vtkActorCollection* ActorManager::GetEdgeActors() const
{
    return m_edgeActors;
}

vtkActorCollection* ActorManager::GetPointActors() const
{
    return m_pointActors;
}

PickMode ActorManager::GetActorMode(vtkActor* actor) const
{
    auto itor = m_actorInfoMap.find(actor);
    if(itor != m_actorInfoMap.end())
    {
        return itor->second.mode;
    }

    return PickMode::VOLUME;
}

int ActorManager::AddActor(vtkActor* actor, PickMode mode, const std::string& name)
{
    int index = -1;

    // 生成名称如果未提供
    std::string actorName = name;
    if(actorName.empty())
    {
        actorName = GenerateActorName(mode, GetActorCount(mode));
    }

    switch(mode)
    {
    case PickMode::VOLUME:
        index = m_volumeActors->GetNumberOfItems();
        m_volumeActors->AddItem(actor);
        break;
    case PickMode::FACE:
        index = m_faceActors->GetNumberOfItems();
        m_faceActors->AddItem(actor);
        break;
    case PickMode::EDGE:
        index = m_edgeActors->GetNumberOfItems();
        m_edgeActors->AddItem(actor);
        break;
    case PickMode::POINT:
        index = m_pointActors->GetNumberOfItems();
        m_pointActors->AddItem(actor);
        break;
    }

    m_actorInfoMap[actor] = {mode, actorName, index};
    return index;
}

int ActorManager::GetActorCount(PickMode mode) const
{
    switch(mode)
    {
    case PickMode::VOLUME: return m_volumeActors->GetNumberOfItems();
    case PickMode::FACE: return m_faceActors->GetNumberOfItems();
    case PickMode::EDGE: return m_edgeActors->GetNumberOfItems();
    case PickMode::POINT: return m_pointActors->GetNumberOfItems();
    }
    return 0;
}

std::string ActorManager::GenerateActorName(PickMode mode, int index) const
{
    std::string prefix;
    switch(mode)
    {
    case PickMode::VOLUME: prefix = "Volume"; break;
    case PickMode::FACE: prefix = "Face"; break;
    case PickMode::EDGE: prefix = "Edge"; break;
    case PickMode::POINT: prefix = "Point"; break;
    }
    return prefix + "_" + std::to_string(index);
}


//-------------------------------实列化--------------------
static std::shared_ptr<ActorManager> ActorManagerInstance = nullptr;
std::shared_ptr<ActorManager> GetActorManagerInstance()
{
    if(!ActorManagerInstance)
    {
        ActorManagerInstance = std::make_shared<ActorManager>();
    }

    return ActorManagerInstance;
}



